//
//  BBLargeImageView.m
//  LargeImage
//
//  Created by box on 14-3-25.
//  Copyright (c) 2014年 box. All rights reserved.
//

/*! 使用示例
 BBLargeImageView *largeView = [BBLargeImageView largeImageView];
 // [largeView setCurIndex:2 after:0.1 animated:NO];
 largeView.dataSource = self;
 largeView.delegate = self;
 largeView.autoAnimate = YES;
 largeView.removeOnGoBack = YES;
 largeView.removeOnTouchImage = NO;
 largeView.adjustFrameToSuperView = YES;
 largeView.toolBarView.hidden = NO;
 [self.view addSubview:largeView];
 */

#import "BBLargeImageView.h"
#import "UIImageView+WebCache.h"

#define LARGE_IMAGEVIEW_TAG 2549
#define LARGE_SCROLLVIEW_TAG 9851
#define LARGE_ANIMATION_DURATION 0.25f


@interface BBLargeImageView()<UIScrollViewDelegate>
{
    id curTargetForDoSomethingBtn;
    SEL curSelectorForDoSomethingBtn;
    BOOL isAnimateIn;
}

@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (retain, nonatomic) IBOutlet UILabel *indicateLbl;
@property (retain, nonatomic) IBOutlet UIButton *backBtn;
@property (retain, nonatomic) IBOutlet UIButton *doSomethingBtn;//默认响应为保存图片到相册事件
@property (strong, nonatomic) IBOutlet UIImageView *doSomeImg;

@end

@implementation BBLargeImageView


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
    }
    return self;
}

- (void)awakeFromNib
{
    _tableView.layer.transform = CATransform3DMakeRotation(-M_PI_2, 0., 0., 1.);
    _tableView.frame = self.bounds;
    _curIndex = 0;
    
    self.backgroundColor = [UIColor blackColor];
//    [_doSomethingBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
//    _doSomethingBtn.layer.borderColor = [UIColor whiteColor].CGColor;
//    _doSomethingBtn.layer.borderWidth = 1.0f;
//    _doSomethingBtn.layer.cornerRadius = 5;
//    _doSomethingBtn.clipsToBounds = YES;
//    
//    
//    [_backBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
//    _backBtn.layer.borderColor = [UIColor whiteColor].CGColor;
//    _backBtn.layer.borderWidth = 1.0f;
//    _backBtn.layer.cornerRadius = 5;
//    _backBtn.clipsToBounds = YES;
    
    curSelectorForDoSomethingBtn = @selector(onSaveImage:);
    curTargetForDoSomethingBtn = self;
}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
 // Drawing code
 }
 */

- (void)dealloc {
    [_tableView release];
    [_indicateLbl release];
    [_doSomethingBtn release];
    [_backBtn release];
    [_toolBarView release];
    [super dealloc];
}

- (void)willMoveToSuperview:(UIView *)newSuperview
{
    [super willMoveToSuperview:newSuperview];
}

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    if (_autoAnimate) {
        [self animateIn];
    }
    if (_adjustFrameToSuperView) {
        self.frame = self.superview.bounds;
    }
}

#pragma mark -
#pragma mark self define method

- (void)doSomethingBtnChangeTarget:(id)aTarget action:(SEL)aSelector title:(NSString *)aTitle
{
    [_doSomethingBtn removeTarget:curTargetForDoSomethingBtn action:curSelectorForDoSomethingBtn forControlEvents:UIControlEventTouchUpInside];
    [_doSomethingBtn addTarget:aTarget action:aSelector forControlEvents:UIControlEventTouchUpInside];
    //    [_doSomethingBtn setTitle:aTitle forState:UIControlStateNormal];
    //    [_doSomethingBtn setBackgroundImage:[UIImage imageNamed:aTitle] forState:UIControlStateNormal];
    CGRect imgRec = _doSomeImg.frame;
    imgRec.size = CGSizeMake(26, 26);
    _doSomeImg.frame = imgRec;
    _doSomeImg.image = [UIImage imageNamed:aTitle];
    curTargetForDoSomethingBtn = aTarget;
    curSelectorForDoSomethingBtn = aSelector;
}

- (void)animateIn
{
    isAnimateIn = YES;
    self.userInteractionEnabled = NO;
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    anim.duration = LARGE_ANIMATION_DURATION;
    anim.removedOnCompletion = YES;
    anim.keyTimes = @[@0,@0.5,@1];
    anim.values = @[@0,@0.5,@1];
    anim.delegate = self;
    
    CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim.duration = LARGE_ANIMATION_DURATION;
    opacityAnim.fromValue = [NSNumber numberWithFloat:0.0f];
    opacityAnim.toValue = [NSNumber numberWithFloat:1.0f];
    opacityAnim.removedOnCompletion = YES;
    
    
    [_tableView.layer addAnimation:anim forKey:nil];
    [self.layer addAnimation:opacityAnim forKey:nil];
    
}

- (void)animateOut
{
    isAnimateIn = NO;
    self.userInteractionEnabled = NO;
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    anim.duration = LARGE_ANIMATION_DURATION;
    anim.removedOnCompletion = YES;
    anim.keyTimes = @[@0,@1];
    anim.values = @[@1,@0];
    anim.delegate = self;
    
    CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim.duration = LARGE_ANIMATION_DURATION;
    opacityAnim.fromValue = [NSNumber numberWithFloat:1.0f];
    opacityAnim.toValue = [NSNumber numberWithFloat:0.0f];
    opacityAnim.removedOnCompletion = YES;
    
    [_tableView.layer addAnimation:anim forKey:nil];
    [self.layer addAnimation:opacityAnim forKey:nil];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((LARGE_ANIMATION_DURATION-0.05) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //self.alpha = 0.;
       // _tableView.frame = CGRectZero;
    });
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (flag) {
        self.userInteractionEnabled = YES;
        if (!isAnimateIn) {
            [super removeFromSuperview];
        }
    }
}

- (void)onTapLargeImageView:(UITapGestureRecognizer *)sender
{
    
    if (_delegate && [_delegate respondsToSelector:@selector(largeImageView:didClickImageAtIndex:)]) {
        [_delegate largeImageView:self didClickImageAtIndex:_curIndex];
    }
    
    if (_removeOnTouchImage) {
        [self removeFromSuperview];
    }
}

+ (instancetype)largeImageView
{
    BBLargeImageView *largeImgView = (BBLargeImageView *)[[[NSBundle mainBundle]loadNibNamed:@"BBLargeImageView" owner:nil options:nil]lastObject];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:largeImgView action:@selector(onTapLargeImageView:)];
    [largeImgView.tableView addGestureRecognizer:tap];
    [tap release];
    
    return largeImgView;
}

- (void)setCurIndex:(NSInteger)curIndex
{
    [self setCurIndex:curIndex after:0 animated:NO];
}


- (void)setCurIndex:(NSInteger)curIndex after:(NSTimeInterval)delayTime animated:(BOOL)animated
{
    double delayInSeconds = delayTime;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        
        
        if (curIndex == _curIndex) {
            return;
        }
        if (curIndex >= _count) {
            //NSLog(@"设置的curIndex超出范围");
            return;
        }
        
        _curIndex = curIndex;
        
        [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_curIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:animated];
        [self updateIndicator];
        
        
        
        
    });
}

/*!
 *@description  响应保存图片
 *@function     onSaveImage
 *@param        sender    --保存图片按钮
 *@return       (void)
 */
- (IBAction)onSaveImage:(UIButton *)sender
{
    UIImageView *vImgView = self.visibleImageView;
    if (!vImgView) {
        return;
    }
    
    UIImageWriteToSavedPhotosAlbum(vImgView.image
                                   , self
                                   , @selector(image:didFinishSavingWithError:contextInfo:)
                                   , nil);
}

- (void)removeFromSuperview
{
    _dataSource = nil;
    _delegate = nil;
    if (_autoAnimate) {
        [self animateOut];
    }else{
        [super removeFromSuperview];
    }
}

- (IBAction)onGoBack:(UIButton *)sender {
    
    if (_removeOnGoBack) {
        [self removeFromSuperview];
    }
    
    if (_delegate && [_delegate respondsToSelector:@selector(didClickGoBackOnLargeImageView:)]) {
        [_delegate didClickGoBackOnLargeImageView:self];
    }
}

- (void)reloadData
{
    _curIndex = 0;
    _tableView.contentOffset = CGPointZero;
    [_tableView reloadData];
}

- (UIImageView *)visibleImageView
{
    if (_count == 0) {
        return nil;
    }
    UITableViewCell *cell = [_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:_curIndex inSection:0]];
    UIImageView *imageView = (UIImageView *)[cell viewWithTag:LARGE_IMAGEVIEW_TAG];
    return imageView;
}

- (void)setEnableDoSomeThingBtn:(BOOL)enableDoSomeThingBtn
{
    _enableDoSomeThingBtn = enableDoSomeThingBtn;
    _doSomethingBtn.enabled = _enableDoSomeThingBtn;
}

#pragma mark -
#pragma mark UITableViewDataSource method
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    _count = 0;
    if (_dataSource && [_dataSource respondsToSelector:@selector(numberOfImagesInLargeImageView:)]) {
        _count = [_dataSource numberOfImagesInLargeImageView:self];
    }
    [self updateIndicator];
    return _count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *indentifier = @"cellIndentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier];
    if (!cell) {
        cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier]autorelease];
        cell.backgroundColor = [UIColor blackColor];
        UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:self.bounds];
        scrollView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0., 0., 1.);
        scrollView.tag = LARGE_SCROLLVIEW_TAG;
        scrollView.minimumZoomScale = 1.0f;
        scrollView.maximumZoomScale = 3.0f;
        CGFloat height = 0.0f;
        scrollView.frame = CGRectMake(height ,0, self.frame.size.height, self.frame.size.width);
        scrollView.backgroundColor = [UIColor clearColor];
        scrollView.delegate = self;
        
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.bounds];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        imageView.tag = LARGE_IMAGEVIEW_TAG;
        imageView.backgroundColor = [UIColor blackColor];
        [scrollView addSubview:imageView];
        [imageView release];
        [cell addSubview:scrollView];
        [scrollView release];
        
    }
    
    
    UIScrollView *scrollView = (UIScrollView *)[cell viewWithTag:LARGE_SCROLLVIEW_TAG];
    scrollView.zoomScale = 1.0f;
    UIImageView *imageView = (UIImageView *)[cell viewWithTag:LARGE_IMAGEVIEW_TAG];
    [imageView cancelCurrentImageLoad];
    if (_dataSource && [_dataSource respondsToSelector:@selector(largeImageView:urlOrImageAtIndex:)]) {
        id obj = [_dataSource largeImageView:self urlOrImageAtIndex:indexPath.row];
        if ([obj isKindOfClass:[NSURL class]]) {
            [imageView setImageWithURL:obj];
        }else if ([obj isKindOfClass:[UIImage class]]){
            imageView.image = obj;
        }else if ([obj isKindOfClass:[NSString class]]){
            NSURL *url = [NSURL URLWithString:obj];
            [imageView setImageWithURL:url];
        }
    }else if (_dataSource && [_dataSource respondsToSelector:@selector(largeImageView:urlForImageAtIndex:)]) {
        NSURL *url = [_dataSource largeImageView:self urlOrImageAtIndex:indexPath.row];
        [imageView setImageWithURL:url];
    }else if(_dataSource && [_dataSource respondsToSelector:@selector(largeImageView:imageAtIndex:)]) {
        UIImage *image = [_dataSource largeImageView:self urlOrImageAtIndex:indexPath.row];
        [imageView setImage:image];
    }
    
    return cell;
}

- (void)updateIndicator
{
    _indicateLbl.text = [NSString stringWithFormat:@"%d/%d",_count==0?0:_curIndex+1,_count];
}

#pragma mark -
#pragma mark UITableViewDelegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return _tableView.frame.size.width;
}

#pragma mark -
#pragma mark UIScrollViewDelegate method
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    if (scrollView != _tableView) {
        return [scrollView viewWithTag:LARGE_IMAGEVIEW_TAG];
    }else{
        return nil;
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (scrollView == _tableView) {
        NSInteger newIndex = (NSInteger)(scrollView.contentOffset.y/scrollView.frame.size.width);
        if (_curIndex != newIndex) {
            _curIndex = newIndex;
            UITableViewCell *cell = [_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:_curIndex inSection:0]];
            UIScrollView *scrollView = (UIScrollView *)[cell viewWithTag:LARGE_SCROLLVIEW_TAG];
            [scrollView setZoomScale:1.0f animated:YES];
            [self updateIndicator];
            
            if (_delegate && [_delegate respondsToSelector:@selector(largeImageView:didScrollToImageAtIndex:)]) {
                [_delegate largeImageView:self didScrollToImageAtIndex:_curIndex];
            }
        }
    }
}


#pragma mark -
#pragma mark 保存图片到相册
/*!
 *@description  保存图片完成回调方法
 *@function     image:didFinishSavingWithError:contextInfo:
 *@param        image           --需要保存的图片
 *@param        error           --错误信息
 *@param        contextInfo     --上下文信息
 *@return       (void)
 */
- (void)image:(UIImage *)image
didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo
{
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"图片保存失败" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
        [alert show];
        [alert release];
    }else{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"图片已保存到相册" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
        [alert show];
        [alert release];
    }
}


@end
